import {Component, OnInit, ViewChild} from '@angular/core';
import {FormControl, FormGroup, Validators} from "@angular/forms";
import {BarnSql} from "../entity/barn-sql";
import {BarnSqlService} from "../service/barn-sql.service";
import {ActivatedRoute} from "@angular/router";
import {basicSetup, EditorView} from '@codemirror/basic-setup';
import {Compartment, EditorState} from '@codemirror/state'
import {HighlightStyle, tags} from '@codemirror/highlight'
import {sql} from '@codemirror/lang-sql'
import {NzMessageService} from "ng-zorro-antd/message";
import {ProductService} from "../../product/service/product.service";
import {BarnProduct} from "../../product/entity/barn-product";
import {BarnProject} from "../../project/entity/barn-project";
import {keymap} from "@codemirror/view"
import {defaultTabBinding} from "@codemirror/commands"

@Component({
  selector: 'app-sql-edit',
  templateUrl: './sql-edit.component.html',
  styleUrls: ['./sql-edit.component.less']
})
export class SqlEditComponent implements OnInit {

  remarkMaxLength = BarnSql.remarkMaxLength
  validateForm = new FormGroup({
    sqlTitle: new FormControl(null, [Validators.required, Validators.maxLength(20)]),
    schemaName: new FormControl(null, [Validators.required]),
    remark: new FormControl(null, [Validators.maxLength(this.remarkMaxLength)]),
    productId: new FormControl(),
    pid: new FormControl(null)
  })

  loading = false

  @ViewChild('editor', {static: true})
  holder
  view: EditorView

  isVisible = false
  allProducts: BarnProduct[] = []

  projects: BarnProject[] = []


  constructor(private barnSqlService: BarnSqlService, private routeInfo: ActivatedRoute, private msg: NzMessageService, private productService: ProductService) {
  }

  ngOnInit(): void {
    this.initSqlEditor()
    const pid = this.routeInfo.snapshot.queryParams["pid"];
    if (pid) {
      this.loading = true
      this.barnSqlService.getById(pid).subscribe(value => {
        this.loading = false
        if (value) {
          this.validateForm.patchValue(value);
          const t = this.view.state.update({changes: {insert: value.sqlText, from: 0}});
          this.projects = value.use||[]
          this.view.dispatch(t);
        }
      }, () => this.loading = true);
    }

    const param = new BarnProduct()
    param.enable = '1'
    this.productService.query(param).subscribe(value => {
      this.allProducts = value.data
    })
  }

  submitForm() {
    if (this.validateForm.valid) {

      this.loading = true
      const sql = this.validateForm.getRawValue()
      sql.sqlText = this.view.state.doc.toString()

      // usage
      sql.use = this.projects
      this.barnSqlService.save(sql).subscribe(value => {
        this.loading = false
        this.validateForm.patchValue(value)
        this.msg.success("保存成功")
      }, () => this.loading = false)

    } else {
      for (const i in this.validateForm.controls) {
        this.validateForm.controls[i].markAsDirty();
        this.validateForm.controls[i].updateValueAndValidity();
      }
    }
  }

  get productId(): string {
    return this.validateForm.get('productId').value
  }

  selectProject(p: BarnProject) {
    this.projects.push(p);
    this.isVisible = false
  }

  get disabledIds(): string[] {
    return this.projects ? this.projects.map(value => value.pid) : []
  }

  deleteProject(index) {
    this.projects.splice(index, 1)
  }


  /**
   * 初始化编辑器
   */
  initSqlEditor() {
    const language = new Compartment()
    const tabSize = new Compartment()

    // 设置编辑器样式
    const myTheme = EditorView.theme({
      '&': {
        color: 'white',
        backgroundColor: '#034'
      },
      '.cm-content': {
        caretColor: '#0e9',
        minHeight: '580px'
      },
      '&.cm-focused .cm-cursor': {
        borderLeftColor: '#0e9'
      },
      '&.cm-focused .cm-selectionBackground, ::selection': {
        backgroundColor: '#074'
      },
      '.cm-gutters': {
        backgroundColor: '#045',
        color: '#ddd',
        border: 'none'
      },
      '&.cm-editor': {
        height: '100%'
      }
    }, {dark: true})

    // 设置高亮样式
    const myHighlightStyle = HighlightStyle.define([
      {tag: tags.keyword, color: '#fc6'},
      {tag: tags.comment, color: '#f5d', fontStyle: 'italic'}
    ])

    // 设置编辑器的基本属性
    const state = EditorState.create({
      extensions: [
        basicSetup,
        keymap.of([defaultTabBinding]),
        language.of(sql()),
        tabSize.of(EditorState.tabSize.of(4)),
        myTheme,
        myHighlightStyle
      ]
    })

    // 初始化
    this.view = new EditorView({
      state,
      parent: this.holder.nativeElement
    })

  }

}
